/**
 * Copyright (C), 2015-2018, XXX有限公司
 * FileName: MutiDataSourceExAop
 * Author:   zhouheng
 * Date:     2018/6/20 21:02
 * Description: 数据源切换aop
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.hengby.hengcrud.config.mutidatasource.aop;

import com.hengby.hengcrud.config.mutidatasource.DataSourceContextHolder;
import com.hengby.hengcrud.config.mutidatasource.MutiDataSourceProperties;
import com.hengby.hengcrud.config.mutidatasource.annotation.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 〈一句话功能简述〉<br> 
 * 〈数据源切换aop〉
 *
 * @author zhouheng
 * @create 2018/6/20
 * @since 1.0.0
 */
@Order(value = 1)
@Aspect
@Component
@ConditionalOnProperty(prefix = "heng_crud", name = "muti-datasource-open", havingValue = "true")
@Slf4j
public class MutiDataSourceExAop {
    @Autowired
    public MutiDataSourceProperties mutiDataSourceProperties;

    @Pointcut(value = "@annotation(com.hengby.hengcrud.config.mutidatasource.annotation.DataSource)")
    public void cut(){

    }

    @Before(value = "cut()")
    public void testBefore(){
        log.info("test before....");
    }

    @After(value = "cut()")
    public void testAfter(){
        log.info("test after....");
    }

    @Around(value = "cut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Signature signature = point.getSignature(); // 获取签名
        MethodSignature methodSignature = null;
        if (!(signature instanceof MethodSignature)){ // 检查该签名是否属于方法签名
            throw new IllegalArgumentException("该注解只能用于方法");
        }else {
            methodSignature = (MethodSignature)signature;

            Object target = point.getTarget();
            Method method = target.getClass().getMethod(methodSignature.getName(),methodSignature.getParameterTypes());

            DataSource dataSource = method.getAnnotation(DataSource.class);
            if (dataSource != null){
                DataSourceContextHolder.setDataSource(dataSource.name());
                log.debug("设置数据源为："+dataSource.name());
                System.out.println(dataSource.name());
            }else {
                DataSourceContextHolder.setDataSource(mutiDataSourceProperties.deaultDataSourceName);
                log.debug("设置数据源为：dataSourceCurrent");
            }

            try {
                return point.proceed();
            } finally {
                log.debug("清空数据源信息！");
                DataSourceContextHolder.clear();
            }

        }
    }
}